// i.r(t), i.d(t, { default: () => SnapshotsDataModule })

import Module from "./Module"
import Logger from "../utils/Logger"
import SweepData from "../data/SweepData"
import SnapshotsData from "../data/SnapshotsData"
import g from "../math/19674"
import { ReadOnlyError, NotImplementedError } from "../exception/store.exception"
import { SnapshotCreatedMessage } from "../message/snapshot.message"
const _ = new Logger("MpWebSnapshotSerializer")
class MpWebSnapshotSerializer {
  serialize(e: Snapshot) {
    if (!this.validate(e)) return _.info("Cannot serialize invalid snapshot", e), null
    const t = {
        camera_mode: viewToWork(e.metadata.cameraMode),
        camera_position: g.gj(e.metadata.cameraPosition),
        camera_quaternion: funcUtil.getXYZW(g.EV(e.metadata.cameraQuaternion)),
        ortho_zoom: e.metadata.orthoZoom,
        ss_zoom: e.metadata.ssZoom,
        scan_id: e.metadata.scanId,
        is_ortho: e.metadata.cameraMode === viewmodeEnum.Floorplan,
        floorVisibility: e.metadata.floorVisibility
      },
      i = e.category,
      n = `${e.name}.jpg`
    return {
      src: [e.imageBlob, n] as [Blob, string],
      name: e.name,
      metadata: JSON.stringify(t),
      category: i
    }
  }
  validate(e: Snapshot) {
    return !!e.imageBlob
  }
}
import ExpiringResource from "../utils/ExpiringResource"
var M = {
  AUTO: "auto",
  PANORAMA: "panorama",
  TOUR: "tour",
  UNALIGNED: "unaligned",
  USER: "user"
}

import * as THREE from "three"
import Snapshot from "../object/Snapshot"
import snapshotStateEnum from "../enum/snapshotState.enum"
// Generated by https://quicktype.io

export interface Sdfsdfdsf {
  category: string
  download_url: string
  height: number
  metadata: string
  name: string
  sid: string
  signed_src: string
  src: string
  thumbnail_signed_src: string
  url: string
  vision_generated_label: string
  vision_generated_name: string
  vision_image_index: number
  width: number
  overrides: string
  playName: number
  pathAudio: null
  backOpen: null
  closePrev: number
  pathVideo: null
  robotInfo: null
  _hero: boolean
}

const C = new Logger("MpWebSnapshotDeserializer")
const P = {
  [M.AUTO]: categoryEnum.AUTO,
  [M.PANORAMA]: categoryEnum.PANORAMA,
  [M.TOUR]: categoryEnum.TOUR,
  [M.UNALIGNED]: categoryEnum.UNALIGNED,
  [M.USER]: categoryEnum.USER
}
class MpWebSnapshotDeserializer {
  deserialize(e) {
    const t = this.validate(e)
    if (!t) return C.debug("Deserialized invalid snapshot", e), null
    const i = workToView(3 === t.metadata.camera_mode ? 0 : t.metadata.camera_mode),
      n = g.gj(t.metadata.camera_position ? t.metadata.camera_position : new THREE.Vector3())
    let s = g.EV(t.metadata.camera_quaternion || new THREE.Quaternion())
    i !== viewmodeEnum.Floorplan && (s = g.Z(s))
    let o: string = null
    const a = t.metadata.floorVisibility
    if ("object" == typeof a) for (let e = 0; e < a.length; e++) a[e] && (o = e.toString())
    const l = t.metadata.highest_floor
    "number" == typeof l && l > -1 && (o = l.toString())
    const c = {
      cameraMode: i,
      cameraPosition: n,
      cameraQuaternion: s,
      scanId: t.metadata.scan_id || "",
      orthoZoom: t.metadata.ortho_zoom,
      floorId: o,
      ssZoom: t.metadata.ss_zoom || 1,
      floorVisibility: t.metadata.floorVisibility
    }
    const h = P[t.category]
    return new Snapshot().copy({
      sid: t.sid,
      state: snapshotStateEnum.DONE,
      metadata: c,
      thumbnailUrl: new ExpiringResource(t.thumbnail_signed_src, null),
      imageUrl: new ExpiringResource(t.signed_src, null),
      name: t.name,
      is360: "unaligned" === t.category,
      category: h,
      height: t.height,
      width: t.width,
      modified: new Date(Date.parse(t.modified)),
      created: new Date(Date.parse(t.created)),
      visionLabel: t.vision_generated_label,
      visionName: t.vision_generated_name
    })
  }
  validate(e) {
    if (!e) return null
    let t
    try {
      t = JSON.parse(e.metadata)
    } catch (t) {
      return C.info("Failed to parse image metadata: ", e.metadata), null
    }
    return 0 === Object.keys(t).length || "assetType" in t
      ? null
      : e.category in P
      ? Object.assign(Object.assign({}, e), { metadata: t })
      : (C.debug(`Invalid snapshot category ${e.category}`), null)
  }
}
import MpWebStore from "../storage/MpWebStore"
import PrefetchedData from "../utils/PrefetchedData"
import httpEnum from "../enum/http.enum"
import storageTypeEnum from "../enum/storageType.enum"
import categoryEnum from "../enum/category.enum"
import funcUtil from "../utils/func.util"
import { viewToWork, workToView } from "../utils/viewmode.util"
import viewmodeEnum from "../enum/viewmode.enum"
import { MODELDATA } from "../../typing"
import EngineContext from "../EngineContext"

class MpWebSnapshotStore extends MpWebStore<MODELDATA> {
  serializer: MpWebSnapshotSerializer
  deserializer: MpWebSnapshotDeserializer
  constructor(e) {
    super(e)
    this.serializer = new MpWebSnapshotSerializer()
    this.deserializer = new MpWebSnapshotDeserializer()
  }
  async refresh() {
    throw new NotImplementedError("Refresh not implemented for mp_web images")
  }
  async read(): Promise<Record<string, Snapshot>> {
    const { modelId: e } = this.config
    const t = `/scene-portal/api/v1/player/models/${e}`
    let i = PrefetchedData.model ? PrefetchedData.model : await this.request(httpEnum.GET, t)
    if (!i || !Array.isArray(i.images)) return null
    const n = {}
    for (const e of i.images) {
      const t = this.deserializer.deserialize(e)
      t && (n[t.sid] = t)
    }
    return n
  }
  async create(e: Snapshot) {
    const { modelId: t, readonly: i } = this.config
    if (i) throw new ReadOnlyError("Cannot add photo, store is read-only")
    const n = this.serializer.serialize(e)
    if (!n) throw new Error("Failed to upload image")
    const s = new FormData()
    for (const [e, t] of Object.entries(n)) Array.isArray(t) && t[0] instanceof Blob ? s.append(e, t[0], t[1]) : s.append(e, t as string)
    const r = `/scene-portal/api/v1/player/models/${t}/images/`
    const o = await this.request(httpEnum.POST, r, { body: s })
    return this.deserializer.deserialize(o)
  }
  async update(e) {
    const { modelId: t, readonly: i } = this.config
    if (i) throw new ReadOnlyError("Cannot update photo, store is read-only")
    const n = { name: e.name }
    const s = `/scene-portal/api/v1/player/models/${t}/images/${e.sid}`
    const r = await this.request(httpEnum.PATCH, s, { body: n })
    return this.deserializer.deserialize(r)
  }
  async delete(e: string) {
    const { modelId, readonly } = this.config
    if (readonly) throw new ReadOnlyError("Cannot delete photo, store is read-only")
    const n = `/scene-portal/api/v1/player/models/${modelId}/images/${e}`
    await this.request(httpEnum.DELETE, n)
    return !0
  }
}
const R = new Logger("snapshots")
export default class SnapshotsDataModule extends Module {
  engine: EngineContext
  store: MpWebSnapshotStore
  sweepData: SweepData
  snapshotsData: SnapshotsData
  constructor() {
    super(...arguments)
    this.name = "snapshots-data"
  }
  async init(e, t: EngineContext) {
    this.engine = t
    this.store = this.getStore(e)
    const n = (await this.store.read()) || {}
    this.sweepData = await t.market.waitForData(SweepData)
    for (const e in n) this.processSnapshot(n[e])
    this.snapshotsData = new SnapshotsData(n)
    this.snapshotsData.onStale = () => this.store.read()
    t.market.register(this, SnapshotsData, this.snapshotsData)
  }
  async uploadSnapshot(e) {
    const i = await this.store.create(e)
    i && (this.processSnapshot(i), this.snapshotsData.add(i), this.engine.broadcast(new SnapshotCreatedMessage(i)))
    return i
  }
  async renameSnapshot(e, t) {
    const i = this.snapshotsData.get(e)
    if (t !== i.name) return (i.name = t), i.commit(), this.snapshotsData.commit(), this.store.update(i)
  }
  async deleteSnapshot(e: string) {
    return this.store.delete(e)
  }
  getStore(e) {
    if (this.store) return this.store
    const { modelId, baseUrl, queue } = e
    R.info(`Loading Snapshots from ${storageTypeEnum.JSONSTORE}`)
    return new MpWebSnapshotStore({
      modelId,
      readonly: true,
      queue,
      baseUrl
    })
  }
  processSnapshot(e: Snapshot) {
    const t = e.metadata.cameraMode === viewmodeEnum.Panorama
    const i = !this.sweepData.isSweepAligned(e.metadata.scanId)
    e.is360 = t && i
    if (t) {
      const t = this.sweepData.getSweep(e.metadata.scanId)
      t && e.metadata.cameraPosition.copy(t.position)
    }
    e.name && e.name.match(/^[0-9.]+_[0-9.]+$/) && ((e.name = ""), e.commit())
  }
}
